//
// Created by YueChuan on 2023/5/4.
//

#include "http_session.h"


namespace yuechuan {
    namespace http {
        HttpSession::HttpSession(Socket::ptr sock, bool owner) :
                SocketStream(sock, owner) {

        }

        HttpRequest::ptr HttpSession::recvRequest() {
            HttpRequestParser::ptr parser(new HttpRequestParser);
            uint64_t buff_size = HttpRequestParser::GetHttpRequestBufferSize();
            std::shared_ptr<char> buffer(new char[buff_size], [](char *ptr) {
                delete[] ptr;
            });
            char *data = buffer.get();
            int offset = 0;
            do {
                int len = read(data + offset, buff_size - offset);
                if (len <= 0) {
                    close();
                    return nullptr;
                }
                len += offset;
                size_t nparser = parser->execute(data, len);
                if (parser->hasError()) {
                    close();
                    return nullptr;
                }
                offset = len - nparser;
                if (offset == (int) buff_size) {
                    close();
                    return nullptr;
                }
                if (parser->isFinished()) {
                    break;
                }
            } while (true);

            int64_t length = parser->getContentLength();
            // 处理POST类型，且Content-type 是jpeg
            HttpMethod method = parser->getMethod();
            if(method == HttpMethod::POST)
            {
                std::ostream &ss = parser->getData()->getFileOstream();
                ss << data;
            }
            if (length > 0) {
                std::string body;
                body.resize(length);
                int len = 0;
                if (length >= offset) {
                    memcpy(&body[0], data, offset);
                    len = offset;
                } else {
                    memcpy(&body[0], data, length);
                    len = length;
                }
                length -= offset;
                if (length > 0) {
                    if (readFixSize(&body[len], length) <= 0) {
                        close();
                        return nullptr;
                    }
                }
                parser->getData()->setBody(body);
            }
            parser->getData()->init();
            return parser->getData();
        }

        int HttpSession::sendResponse(HttpResponse::ptr rsp) {
            std::stringstream ss;
            ss << *rsp;
            std::string data = ss.str();
            return writeFixSize(data.c_str(), data.size());
        }
    }
}